package com.triones.yjj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.Const;
import com.ruoyi.common.utils.DateUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysConfigService;
import com.triones.biz.infra.entity.file.FileConfigDO;
import com.triones.biz.infra.entity.file.vo.FileConfigVO;
import com.triones.biz.infra.entity.file.vo.FileVO;
import com.triones.biz.infra.mapper.file.FileConfigMapper;
import com.triones.biz.infra.service.file.FileService;
import com.triones.framework.common.util.StringUtil;
import com.triones.framework.file.core.client.local.LocalFileClientConfig;
import com.triones.yjj.entity.*;
import com.triones.yjj.entity.bo.WxShareParams;
import com.triones.yjj.entity.vo.*;
import com.triones.yjj.mapper.*;
import com.triones.yjj.service.ShareService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

/**
 * 分享相关 service 业务实现
 *
 * @Author: triones
 */
@Service
@RequiredArgsConstructor
public class ShareServiceImpl implements ShareService {

    private final ShareMapper shareMapper;

    private final ShareRecordMapper shareRecordMapper;

    private final OrderMapper orderMapper;

    private final WxUserShareRecordMapper wxUserShareRecordMapper;

    private final ActivityMapper activityMapper;

    private final InviteRewardMapper inviteRewardMapper;

    private final ActivityPrizeMapper activityPrizeMapper;

    private final RuoYiConfig ruoYiConfig;

    private final FileConfigMapper fileConfigMapper;

    private final FileService fileService;

    @Autowired
    private ISysConfigService sysConfigService;
    /**
     * 查询分享排行列表
     * @param activityId
     * @param pageQuery
     * @return
     */
    public TableDataInfo<WxShareSortVO> selectShareSortPageList(Long activityId, PageQuery pageQuery) {
        QueryWrapper<ShareDO> wrapper = new QueryWrapper<>();
        // 默认排序 时间倒叙
        if (StringUtils.isBlank(pageQuery.getOrderByColumn()) || StringUtils.isBlank(pageQuery.getIsAsc())) {
            wrapper.lambda().orderByDesc(ShareDO::getSpreadNumber);
        }
        wrapper.eq("s.product_id", activityId);
        Page<WxShareSortVO> result = shareMapper.selectShareSortPageList(pageQuery.build(), wrapper);
        return TableDataInfo.build(result);
    }

    public ShareVO getMemberShareInfo(Long activityId, Long memberId, Long userId) {
        QueryWrapper<ShareDO> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id",memberId);
        wrapper.eq("user_id",userId);
        wrapper.eq("product_id", activityId);wrapper.last( " LIMIT 1");

        ShareVO result = shareMapper.selectVoOne(wrapper);
        return result;
    }

    public Long saveShare(Long activityId,Long staffId, MemberDetailVO memberDetailVO) {
        QueryWrapper<ShareDO> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id",memberDetailVO.getId());
        wrapper.eq("user_id",memberDetailVO.getUserId());
        wrapper.eq("product_id", activityId);wrapper.last( " LIMIT 1");
        ShareVO shareVO = shareMapper.selectVoOne(wrapper);
        Long shareId = 0l;
        if(ObjectUtil.isEmpty(shareVO)){
            ShareDO shareDO = new ShareDO();
            shareDO.setStaffId(staffId);
            shareDO.setMemberId(memberDetailVO.getId());
            shareDO.setMemberWxUserId(memberDetailVO.getWxUserId());
            shareDO.setProductId(activityId);
            shareDO.setProductType(1);//产品类型 1活动 2商品
            shareDO.setShareNumber(1);//分享次数
            shareDO.setSpreadNumber(0);//传播次数
            shareDO.setMemberBuyNumber(0);//带来的购买人数
            shareDO.setBuyNumber(0);//带来的购买次数
            shareDO.setPayTotal(BigDecimal.ZERO);//带来的总的支付金额
            //查询是否报名
            Long count = applyCount(memberDetailVO,activityId);
            if(count>0l){
                shareDO.setEnrollStatus(1);//1已报名
            }else{
                shareDO.setEnrollStatus(2);//未报名
            }
            shareDO.setUserId(memberDetailVO.getUserId());//系统用户
            shareMapper.insert(shareDO);
            shareVO = new ShareVO();
            BeanUtil.copyProperties(shareDO,shareVO);
            saveWxUserShare(shareVO);
            return shareDO.getId();
        }else{
            UpdateChainWrapper<ShareDO> wrapperOrder = new UpdateChainWrapper<>(shareMapper);
            if(shareVO.getEnrollStatus().intValue()==2){
                Long count = applyCount(memberDetailVO,activityId);
                if(count>0l){
                    wrapperOrder.set("enroll_status",1);//1已报名
                }
            }

            wrapperOrder.setSql(" share_number=share_number+1 ");
            wrapperOrder.eq("id",shareVO.getId());
            wrapperOrder.update();
            saveWxUserShare(shareVO);
        }
        return shareVO.getId();
    }

    public Long saveShareRecord(WxShareParams params, MemberDetailVO memberDetailVO) {
        ShareDO shareDO = shareMapper.selectById(params.getShareId());
        Long recordId = 0L;
        if (ObjectUtil.isNotEmpty(shareDO)){
            //查询分享staffId
            //判断用户是否已有分享记录
            QueryWrapper<ShareRecordDO> wrapperCount = new QueryWrapper<>();
            wrapperCount.eq("share_id",shareDO.getId());
            wrapperCount.eq("passive_member_id",memberDetailVO.getId());
            Long count = shareRecordMapper.selectCount(wrapperCount);
            if(count.intValue() == 0){
                ShareRecordDO shareRecordDO = new ShareRecordDO();
                shareRecordDO.setShareStaffId(shareDO.getStaffId());
                shareRecordDO.setStaffWxUserId(shareDO.getMemberWxUserId());
                shareRecordDO.setShareId(shareDO.getId());
                if (params.getShareRecordId() == null) {
                    shareRecordDO.setPreviousShareRecordId(0L);
                }
                shareRecordDO.setPreviousShareRecordId(params.getShareRecordId());
                shareRecordDO.setUserId(shareDO.getUserId());
                shareRecordDO.setPassiveMemberId(memberDetailVO.getId());
                shareRecordDO.setPassiveMemberWxUserId(memberDetailVO.getWxUserId());
                shareRecordMapper.insert(shareRecordDO);
                recordId = shareRecordDO.getId();
                //传播+1
                UpdateChainWrapper<ShareDO> wrapperOrder = new UpdateChainWrapper<>(shareMapper);
                wrapperOrder.setSql(" spread_number=spread_number+1 ");
                wrapperOrder.eq("id",shareDO.getId());
                wrapperOrder.update();
                ActivityDO activityDO =  activityMapper.selectById(shareDO.getProductId());
                if(ObjectUtil.isNotEmpty(activityDO)){
                    //判断用户是否增加邀请奖励
                    WxInviteRewardConfigVO wxInviteRewardConfigVO =  getContentInviteRewardConfig(activityDO.getContent());
                    if(ObjectUtil.isNotEmpty(wxInviteRewardConfigVO)){
                        if(wxInviteRewardConfigVO.getIsOpenInvite()){
                            if("ruleB".equals(wxInviteRewardConfigVO.getComputeWay())){
                                saveOrUpdateInviteReward(shareDO);
                            }
                        }
                    }
                }
            }
            /*else{
                wrapperCount.last(" LIMIT 1");
                ShareRecordVO shareRecordVO = shareRecordMapper.selectVoOne(wrapperCount) ;
                if (ObjectUtil.isNotEmpty(shareRecordVO)){
                    recordId = shareRecordVO.getId();
                }
            }*/
            ShareRecordDO shareRecordDO = new ShareRecordDO();
            shareRecordDO.setShareStaffId(shareDO.getStaffId());
            shareRecordDO.setStaffWxUserId(shareDO.getMemberWxUserId());
            shareRecordDO.setShareId(shareDO.getId());
            if (params.getShareRecordId() == null) {
                shareRecordDO.setPreviousShareRecordId(0L);
            } else {
                shareRecordDO.setPreviousShareRecordId(params.getShareRecordId());
            }
            shareRecordDO.setUserId(shareDO.getUserId());
            shareRecordDO.setPassiveMemberId(memberDetailVO.getId());
            shareRecordDO.setPassiveMemberWxUserId(memberDetailVO.getWxUserId());
            shareRecordMapper.insert(shareRecordDO);
            recordId = shareRecordDO.getId();
            return  recordId;

        }else {
            return 0l;
        }
    }
    private WxInviteRewardConfigVO getContentInviteRewardConfig(String content){
        HashMap map = JSONUtil.toBean(content, HashMap.class);
        if(ObjectUtil.isNotEmpty(map)){
            WxInviteRewardConfigVO wxDistributionVO = JSONUtil.toBean(map.get("invite_reward_config").toString(), WxInviteRewardConfigVO.class);
            return wxDistributionVO;
        }
        return null;
    }
    private  void  saveOrUpdateInviteReward(ShareDO shareDO){
        QueryWrapper<InviteRewardDO> wrapper = new QueryWrapper<>();
        wrapper.eq("activity_id",shareDO.getProductId());
        wrapper.eq("member_id",shareDO.getMemberId());
        wrapper.eq("user_id",shareDO.getUserId());
        wrapper.eq("verification_status",1);
        InviteRewardDO inviteRewardDO =  inviteRewardMapper.selectOne(wrapper);

        if (ObjectUtil.isEmpty(inviteRewardDO)){
            inviteRewardDO = new InviteRewardDO();
            inviteRewardDO.setActivityId(shareDO.getProductId());
            inviteRewardDO.setMemberId(shareDO.getMemberId());
            inviteRewardDO.setMemberWxUserId(shareDO.getMemberWxUserId());
            ActivityPrizeVO activityPrizeVO =  getPrizeIdByNum(shareDO.getProductId(),1);
            inviteRewardDO.setPrizeId(activityPrizeVO.getId());
            if(activityPrizeVO.getRequirementInviteNumber().intValue()==1){
                inviteRewardDO.setStatus(1);
            }else{
                inviteRewardDO.setStatus(0);
            }
            String verificationCode =  StringUtil.createSn(3);
            String verificationCodeQr =  createQr(verificationCode,"invite_prize",shareDO.getMemberId()+"");
            inviteRewardDO.setVerificationCode(verificationCode);
            inviteRewardDO.setVerificationQrCode(verificationCodeQr);
            inviteRewardDO.setVerificationStatus(1);
            inviteRewardDO.setUserId(shareDO.getUserId());
            inviteRewardDO.setInviteNumber(1);
            inviteRewardMapper.insert(inviteRewardDO);
        }else {
            int inviteNum = inviteRewardDO.getInviteNumber()+1;
            ActivityPrizeVO activityPrizeVO =  getPrizeIdByNum(shareDO.getProductId(),inviteNum);
            UpdateWrapper<InviteRewardDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("invite_number",inviteNum);
            if(!inviteRewardDO.getPrizeId().equals(activityPrizeVO.getId())){
                updateWrapper.set("prize_id",activityPrizeVO.getId());
                //1：已达成、2：已升级
                if(inviteNum>=activityPrizeVO.getRequirementInviteNumber()){
                    updateWrapper.set("status",1);
                }else{
                    updateWrapper.set("status",2);
                }
            }
            updateWrapper.eq("id",inviteRewardDO.getId());
            inviteRewardMapper.update(inviteRewardDO,updateWrapper);
        }
    }
    private ActivityPrizeVO getPrizeIdByNum (Long activityId,int num){
        QueryWrapper<ActivityPrizeDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id",activityId);
        queryWrapper.orderByAsc("requirement_invite_number");
        List<ActivityPrizeVO> list =  activityPrizeMapper.selectVoList(queryWrapper);
        ActivityPrizeVO returnActivityPrizeVO = new ActivityPrizeVO();
        if(list!=null && list.size()>0){
            for (ActivityPrizeVO activityPrizeVO:list){
                if(num<activityPrizeVO.getRequirementInviteNumber().intValue()){
                    returnActivityPrizeVO = activityPrizeVO;
                    break;
                }
            }
        }
        return returnActivityPrizeVO;
    }

    private String createQr(String key,String type,String orderNo){
        String basePath = sysConfigService.selectConfigByKey("sys.base.file.dir");
        if(StringUtils.isEmpty(basePath)){
            basePath = "/files/";
        }
      /*  QueryWrapper<FileConfigDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("master",1);
        queryWrapper.eq("deleted",0);
        queryWrapper.last(" LIMIT 1");
        FileConfigVO configVO = fileConfigMapper.selectVoOne(queryWrapper);
        LocalFileClientConfig clientConfig = (LocalFileClientConfig) configVO.getConfig();
        String basePath = clientConfig.getBasePath();*/
        String path = ruoYiConfig.getName() + "/"+type+"/"+orderNo+"/"+"qrcode.png";
//        String domain = clientConfig.getDomain();
        String content = "";
        if("order".equals(type)){
            content = Const.STAFF_ORDER_VERIFICATION.replace("ORDERID",key).replace("TYPE","1");
//            content = Const.STAFF_ORDER_VERIFICATION.replace("ORDERID","1").replace("TYPE","1");
        }else{//invite_prize
            content = Const.STAFF_ORDER_VERIFICATION.replace("ORDERID",key).replace("TYPE","2");
//            content = Const.STAFF_ORDER_VERIFICATION.replace("ORDERID","1").replace("TYPE","2");
        }
//        StringUtil.createQr(content,basePath+path);
        File file =  StringUtil.getCreateQrFile(content, basePath + path);
        try {
            FileInputStream fis = new FileInputStream(file);
            FileVO fileVo = fileService.upload(file.getName(),null, IoUtil.readBytes(fis),null);
            fis.close();
            return fileVo.getUrl();
        } catch (IOException e) {
            e.printStackTrace();
        }

//        String prePath = domain+"/infra/file/"+configVO.getId()+"/get/";
        return null;
    }
    /**
     * 员工分享信息
     * @param activityId
     * @param wxStaffDetailVO
     */
    public Long saveStaffShare(Long activityId, WxStaffDetailVO wxStaffDetailVO) {
        //根据Staff
        QueryWrapper<ShareDO> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id",wxStaffDetailVO.getMemberId());
        wrapper.eq("user_id",wxStaffDetailVO.getUserId());
        wrapper.eq("product_id", activityId);wrapper.last( " LIMIT 1");
        ShareVO shareVO = shareMapper.selectVoOne(wrapper);
        Long shareId = 0l;
        if(ObjectUtil.isEmpty(shareVO)){
            ShareDO shareDO = new ShareDO();
            shareDO.setStaffId(wxStaffDetailVO.getId());
            shareDO.setMemberId(wxStaffDetailVO.getMemberId());
            shareDO.setMemberWxUserId(wxStaffDetailVO.getWxUserId());
            shareDO.setProductId(activityId);
            shareDO.setProductType(1);//产品类型 1活动 2商品
            shareDO.setShareNumber(1);//分享次数
            shareDO.setSpreadNumber(0);//传播次数
            shareDO.setMemberBuyNumber(0);//带来的购买人数
            shareDO.setBuyNumber(0);//带来的购买次数
            shareDO.setPayTotal(BigDecimal.ZERO);//带来的总的支付金额
            //查询是否报名
            QueryWrapper<OrderDO> wrapperOrder = new QueryWrapper<>();
            wrapperOrder.eq("member_id",wxStaffDetailVO.getMemberId());
            wrapperOrder.eq("activity_id",activityId);
            wrapperOrder.eq("user_id",wxStaffDetailVO.getUserId());
            wrapperOrder.in("status",2,5);
            Long count = orderMapper.selectCount(wrapperOrder);
            if(count>0l){
                shareDO.setEnrollStatus(1);//1已报名
            }else{
                shareDO.setEnrollStatus(2);///未报名
            }
            shareDO.setUserId(wxStaffDetailVO.getUserId());//系统用户
            shareMapper.insert(shareDO);
            shareId = shareDO.getId();

            shareVO = new ShareVO();
            BeanUtil.copyProperties(shareDO,shareVO);
            saveWxUserShare(shareVO);
        }else{
            ShareDO shareDO = new ShareDO();
            BeanUtil.copyProperties(shareVO,shareDO);
            shareDO.setShareNumber(shareDO.getShareNumber() + 1);
            shareMapper.updateById(shareDO);
            shareId = shareVO.getId();
        }
        return shareId;
    }


    private void saveWxUserShare(ShareVO shareVO){
        WxUserShareRecordDO wxUserShareRecordDO = new WxUserShareRecordDO();
        wxUserShareRecordDO.setProductId(shareVO.getProductId());
        wxUserShareRecordDO.setProductType(shareVO.getProductType());
        wxUserShareRecordDO.setWxUserId(shareVO.getMemberWxUserId());
        wxUserShareRecordDO.setUserId(shareVO.getUserId());
        wxUserShareRecordMapper.insert(wxUserShareRecordDO);
    }

    /**
     * 今日分享次数
     * @param staffDetailVO
     * @param activityId
     * @return
     */
    public Long getTodayShareCount(WxStaffDetailVO staffDetailVO,Long activityId){
        QueryWrapper<WxUserShareRecordDO> wrapper = new QueryWrapper<>();
        wrapper.eq("wx_user_id",staffDetailVO.getWxUserId());
        wrapper.eq("product_id",activityId);
        wrapper.eq("product_type",1);
        wrapper.eq("user_id",staffDetailVO.getUserId());
        wrapper.eq("DATE_FORMAT(create_time,'%Y-%m-%d')", DateUtil.getDay());
        return wxUserShareRecordMapper.selectCount(wrapper);
    }

    /**
     * 详情详情
     * @param shareId
     * @return
     */
    public WxShareVO getMemberShareDetail(Long shareId) {
        WxShareVO result = shareMapper.getShareDetail(shareId);
        return result;
    }

    /**
     * 查询用户是否报名
     * @param memberDetailVO
     * @param activityId
     * @return
     */
    private Long applyCount(MemberDetailVO memberDetailVO,Long activityId){
        //查询是否报名
        QueryWrapper<OrderDO> wrapperOrder = new QueryWrapper<>();
        wrapperOrder.eq("member_id",memberDetailVO.getId());
        wrapperOrder.eq("activity_id",activityId);
        wrapperOrder.eq("user_id",memberDetailVO.getUserId());
        wrapperOrder.in("status",2,5);
        Long count = orderMapper.selectCount(wrapperOrder);
        return count;
    }
}
